Writing computer software completely free of bugs and related problems may be difficult. For example, it may be more difficult to determine that a problem exists since the problem (e.g., a bug) may occur under specific circumstances. In another example, it may be difficult to reproduce a situation, which may lead to the occurrence of the problem (e.g., bug).
Conventional debugging techniques (e.g., to debug software) may include conventional debuggers, tracing, runtime supervision, reverse execution and simulators.
Some bugs may produce effects, which may appear indirectly, for example, a substantially long time after the code containing the bug may have been executed. The effects of such a bug may be observed, however, determining the origin of the effects (i.e., the location of the bug) may not be clear at that time.
Random memory corruption may be an example of such a bug. Software may conventionally run in one direction, for example, forward. A conventional approach to determining the origin of the effects of the bug may be to rerun the software and stop processing prior to the end (i.e., at an earlier point) and analyze possible causes of the problem (e.g., the bug). However, this may be time consuming and may not produce the desired results, for example, due to the erratic behavior of software, the complexity of modern computers, and the difficulty in the reproduction of hardware and/or software states. Determining at what point to stop the processing may also be difficult.
A conventional reversible computer may run calculations both forwards and backwards. In conventional reversible logic the computer may not discard information, and thus may be symmetrical in time.
In conventional debugging both the trace (i.e., the output of events of interest) and the post mortem dump (i.e., or what we today would call a core dump, or a “dump” of the raw state of the computer at the time of an error) may be defined. Core dumps may be interactive, in that a program (e.g., a debugger) may freeze and inspect another program (e.g., the program being debugged).
A conventional reverse computation (e.g., using a computer) method may backup execution of the program to a point of the error after it may be noticed and to re-execute the program under control of a diagnostic routine. Foe example, tracing, the programming language, and the compiler may be leveraged to track a necessary state for reversing some arbitrary execution. This may be done in various ways, for example, software may be augmented with instructions for gathering data sufficient to reverse out of any computation or decision.
Reverse execution may reverse the state of the system in time without manual, time consuming, stop—debug—restart cycles. Conventional reverse execution has been limited to smaller parts of the system (e.g. the state of a single program). One example of conventional reverse execution is instruction-level reverse execution. In conventional instruction-level reverse execution, executed code may be analyzed and a reverse program, which may undo the effect of forward execution, may be generated.
Conventional methods may reverse execute individual and/or parallel programs, and may use a virtual machine to do so.